import { makeObservable } from "mobx";

import { helper } from "vendor/utils/T";
import prompt from "vendor/utils/prompt";
import { type CEComponentType } from "@/components/app/earth3dVis";

import type { SimulationStore } from "./index";
import { EnumBuildMode } from "../constants";

// 设备覆盖物类型
type DeviceOverlayType = CEComponentType["Billboard"] | CEComponentType["Model"];

// 局域网数据结构
interface LocalNetworkData{
    deviceList: DeviceOverlayType[];
    relation:{
        // 模型ID对应模型ID列表
        [index: string]:string[];
    }
}

export class LocalNetworkStore{
    private readonly simulationStore: SimulationStore;
    private buildMode: string;

    // 矢量layer
    private vectorLayer: CEComponentType["VectorLayer"];

    // Primitive layer
    private primitiveLayer: CEComponentType["PrimitiveLayer"];

    // 正在移动的覆盖物
    private movingOverlay: DeviceOverlayType;

    // 选中的连线设备
    private selectedConnectLineDeviceList: DeviceOverlayType[] = [];

    // 局域网数据
    localNetworkData: LocalNetworkData = {
        deviceList: [],
        relation:{}
    }

    constructor(simulationStore: SimulationStore) {
        makeObservable(this,{});
        this.simulationStore = simulationStore;
        this.init();
    }

    /**
     * 添加设备
     */
    addDevice = (deviceType: string) => {
        const { gisMapStore, initData } = this.simulationStore;
        const { CE } = gisMapStore.cesiumUtil;
        const deviceTypeToInfo = helper.convertArrayToObj(initData.localNetworkDeviceList);
        this.buildMode = EnumBuildMode.movingDevice;
        this.clearState();

        // /*
        // lng: 116.383129662412,
        // lat: 39.84286109172407,
        //  */
        // const lng = 117;
        // const lat = 40;

        const { renderer } = deviceTypeToInfo[deviceType];
        switch (renderer.type) {
            case "image":
                this.movingOverlay = new CE.Billboard(new CE.Position(1, 1), renderer.sourceUrl);
                this.movingOverlay.size = [30, 20];
                this.movingOverlay.setStyle({
                    color: CE.Color.BLACK,
                })
                break
            case "gltf":
                // this.movingOverlay = new CE.Model(new CE.Position(lng, lat), renderer.sourceUrl);
                this.movingOverlay = new CE.Model(new CE.Position(1, 1), renderer.sourceUrl);
                this.movingOverlay.setStyle({
                    color: CE.Color.BLACK,
                    minimumPixelSize: 80,  // 最小像素大小
                });
                break
            default:
                return;
        }

        this.movingOverlay.id = this.mkDeviceId() + "_" + deviceType;
        this.vectorLayer.addOverlay(this.movingOverlay);
    }

    /**
     * 添加连线
     */
    addConnectLine = () => {
        prompt.info("注意:请依次点击2个设备进行连线!!!")
        this.buildMode = EnumBuildMode.connectLine;
        this.clearState();
    }

    /**
     * 获取初始化数据
     */
    getInitData = () => {
        const {  initData } = this.simulationStore;
        return initData;
    }

    /**
     * 获取局域网覆盖面积
     */
    getCoverArea = () => {
        const { cesiumUtil } = this.simulationStore.gisMapStore;
        const { CE, viewer } = cesiumUtil;
        // const { Cesium } = CE.Namespace;

        const { deviceList, relation } = this.localNetworkData;
        let centerLng = 0;
        let centerLat = 0;
        let effectRadius = 0;

        if(deviceList.length > 1) {
            const lngList: number[] = [];
            const latList: number[] = [];
            deviceList.forEach((device) => {
                const {lng, lat} = device.position;
                lngList.push(lng);
                latList.push(lat);
            });

            const maxLng = Math.max(...lngList);
            const maxLat = Math.max(...latList);
            const minLng = Math.min(...lngList);
            const minLat = Math.min(...latList);
            centerLng = (maxLng + minLng) / 2;
            centerLat = (maxLat + minLat) / 2;

            // 设备所占用的面积半径
            const deviceAreaRadius = CE.Position.fromObject({
                lng: minLng,
                lat: minLat
            }).distance(CE.Position.fromObject({lng: maxLng, lat: maxLat})) / 2;
            // 设备信号影响范围半径,
            effectRadius = deviceAreaRadius + deviceAreaRadius / 2;
        }else if (deviceList.length == 1){
            centerLng = deviceList[0].position.lng;
            centerLat = deviceList[0].position.lat;
            effectRadius = 10000;
        }

        return {
            center: CE.Position.fromObject({lng: centerLng, lat: centerLat}),
            radius: effectRadius,
        }
    }

    /**
     * 模拟攻击局域网
     */
    mockAttack = () => {
        const { cesiumUtil } = this.simulationStore.gisMapStore;
        const { CE, viewer } = cesiumUtil;
        const { center, radius} = this.getCoverArea();
        if (radius == 0){
            prompt.error("请先建立局域网!")
            return false;
        }


        // const center = CE.Position.fromObject({lng: 93.16742175078915, lat: 37.65618135226457})
        // const radius = 551882.3392827063;

        const vectorLayer = new CE.VectorLayer("mockAttack-vectorLayer").addTo(viewer);
        const primitiveLayer = new CE.PrimitiveLayer("mockAttack-primitiveLayer").addTo(viewer);

        // 绘制防御光弧半球
        const elecEllipsoid= new CE.ElecEllipsoidPrimitive(center,{x:radius,y:radius,z:radius})
        elecEllipsoid.setStyle({
            // color: CE.Color.GREEN
            color: CE.Color.RED
        });
        primitiveLayer.addOverlay(elecEllipsoid);


        // 绘制攻击飞线
        const attackCenter = cesiumUtil.algorithm.getPositionByDistance(center, radius * 2, 180)

        const attackCircle = new CE.Circle(attackCenter, radius/ 2)
        attackCircle.setStyle({
            classificationType:0,
            material: new CE.CircleDiffuseMaterialProperty({
                color:CE.Color.YELLOW.withAlpha(0.2),
                speed: 8.0
            })
        });
        vectorLayer.addOverlay(attackCircle)

        const distPositions = cesiumUtil.algorithm.getCirclePoints(center, radius)
        distPositions.forEach(position =>{
            const line = new CE.FlowLinePrimitive(CE.Math.parabola(attackCenter,position,radius),3)
            line.setStyle({
                speed: 10 * Math.random(),
                color: new CE.Color(0.5, 0.8, 1.0, 1.0)
            })
            primitiveLayer.addOverlay(line)
        });


        return () => {
            viewer.removeLayer(primitiveLayer);
            viewer.removeLayer(vectorLayer);
        }
    }

    destroy = () => {
        const { mapEventBus } = this.simulationStore.gisMapStore;
        mapEventBus.off("mouseMove", this.onMapMouseMove);
        mapEventBus.off("click", this.onMapClick);
    }

    /**
     * 初始化
     */
    private init = () => {
        const { mapEventBus, cesiumUtil } = this.simulationStore.gisMapStore;
        const { CE, viewer } = cesiumUtil;
        this.vectorLayer = new CE.VectorLayer("local-network-vector-layer");
        this.primitiveLayer = new CE.PrimitiveLayer("local-network-primitive-layer");
        viewer.addLayer(this.vectorLayer);
        viewer.addLayer(this.primitiveLayer);

        mapEventBus.on("mouseMove", this.onMapMouseMove);
        mapEventBus.on("click", this.onMapClick);
    }

    /**
     * 清理临时状态
     */
    private clearState = () => {
        if (this.movingOverlay) {
            this.vectorLayer.removeOverlay(this.movingOverlay);
            this.movingOverlay = null;
        }
        this.selectedConnectLineDeviceList = [];
    }

    /**
     * 监听鼠标在地图移动事件
     */
    private onMapMouseMove = (e: any) => {
        // console.log("onMapMouseMove->e->", e)
        if(e) {
            const { CE } = this.simulationStore.gisMapStore.cesiumUtil;
            const {position, wgs84Position, wgs84SurfacePosition} = e;

            switch (this.buildMode){
                case EnumBuildMode.movingDevice: {
                    const movingOverlay = this.movingOverlay;
                    if (movingOverlay && wgs84SurfacePosition) {
                        movingOverlay.position = new CE.Position(wgs84SurfacePosition.lng, wgs84SurfacePosition.lat);
                    }
                    break;
                }
            }
        }
    }

    /**
     * 监听鼠标在地图点击事件
     */
    private onMapClick = (e: any) => {
        if(e) {
            // console.log("onMapClick->e->", e);
            const { CE, viewer } = this.simulationStore.gisMapStore.cesiumUtil;
            const {position, wgs84Position, wgs84SurfacePosition, overlay} = e;

            // 获取相机位置
            // console.log("viewer.cameraPosition->", viewer.cameraPosition);

            // if(overlay){
            //     overlay.setStyle({
            //         color: CE.Color.GREEN,
            //     })
            // }

            switch (this.buildMode) {
                case EnumBuildMode.movingDevice: {
                    if (this.movingOverlay && wgs84SurfacePosition) {
                        this.movingOverlay.position = new CE.Position(wgs84SurfacePosition.lng, wgs84SurfacePosition.lat);

                        this.localNetworkData.deviceList.push(this.movingOverlay);
                        this.movingOverlay = null;
                        this.buildMode = null;
                    }
                    break;
                }
                case EnumBuildMode.connectLine: {
                    if(this.isDevice(overlay)){
                        this.selectedConnectLineDeviceList.push(overlay);
                        if(this.selectedConnectLineDeviceList.length == 2){
                            const [source, dist] = this.selectedConnectLineDeviceList;
                            const polyline = new CE.Polyline([source.position, dist.position]);
                            polyline.setStyle({
                                width: 5,
                                // material: new CE.PolylineLightingTrailMaterialProperty({
                                material: new CE.PolylineLightingMaterialProperty({
                                    color: CE.Color.YELLOW,
                                    // speed: 10.0
                                }),
                                clampToGround: true
                            });
                            polyline.id = this.mkConnectLineId();
                            this.vectorLayer.addOverlay(polyline);

                            // 添加关联关系
                            if(!this.localNetworkData.relation[source.id]) this.localNetworkData.relation[source.id] = [];
                            this.localNetworkData.relation[source.id].push(dist.id);

                            this.buildMode = null;
                        }
                    }
                    break;
                }
            }
        }
    }


    /**
     * 生成设备ID
     */
    private mkDeviceId = () => `device_${Date.now()}`;

    /**
     * 校验是否为设备
     */
    private isDevice = (overlay: CEComponentType["Overlay"]) => !!overlay && /^device_/.test(overlay.id);

    /**
     * 生成连线ID
     */
    private mkConnectLineId = () => `connectLine_${Date.now()}`;

    /**
     * 校验是否为连接线
     */
    private isConnectLine = (overlay: CEComponentType["Overlay"]) => !!overlay && /^connectLine_/.test(overlay.id);
}